<?php
namespace app\wechat\model;
use think\Cache;
use think\Exception;
use think\Model;

class Wechat extends Model{
    public function checkSignature()
    {

        // you must define TOKEN by yourself
        if (!defined("TOKEN")) {
            throw new \think\Exception('TOKEN is not defined!');
        }
        $signature = isset($_GET["signature"]) ? $_GET["signature"] : '';
        $timestamp = isset($_GET["timestamp"]) ? $_GET["timestamp"] : '';
        $nonce = isset($_GET["nonce"]) ? $_GET["nonce"] : '';
        $token = defined('TOKEN') ? TOKEN : '';
        $tmpArr = array($token, $timestamp, $nonce);
        // use SORT_STRING rule
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);
        if ($tmpStr == $signature) {
            return true;
        } else {
            return false;
        }
    }

    //SDK初始化
    public function sdkInit()
    {
        $postStr = isset($GLOBALS["HTTP_RAW_POST_DATA"]) ? $GLOBALS["HTTP_RAW_POST_DATA"] : '';
        if (!empty($postStr)) {
            libxml_disable_entity_loader(true);
            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            return $postObj;
        } else return false;
    }

    //回复单文本信息
    public function responseTextMsg($postObj, $content = '欢迎关注我们的公众号！')
    {
        $fromUsername = isset($postObj->FromUserName) ? $postObj->FromUserName : '';
        $toUsername = isset($postObj->ToUserName) ? $postObj->ToUserName : '';
        $keyword = isset($postObj->Content) ? trim($postObj->Content) : '';
        $time = time();
        $msgType = 'text';
        $textTpl = "<xml>
                    <ToUserName><![CDATA[%s]]></ToUserName>
                    <FromUserName><![CDATA[%s]]></FromUserName>
					<CreateTime>%s</CreateTime>
					<MsgType><![CDATA[%s]]></MsgType>
					<Content><![CDATA[%s]]></Content>
					<FuncFlag>0</FuncFlag>
					</xml>";
        if (!empty($keyword) && !$content) {
            //这里可自定义自动回复单文本内容
            $content = "Welcome to wechat world!";
        }
        echo sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $content);
    }

//    回复图文信息
    public function responseGraphicMsg($postObj, $graphicArr)
    {
        $fromUsername = isset($postObj->FromUserName) ? $postObj->FromUserName : '';
        $toUsername = isset($postObj->ToUserName) ? $postObj->ToUserName : '';
        $time = time();
        $template = '<xml>
                     <ToUserName><![CDATA['.$fromUsername.']]></ToUserName>
                     <FromUserName><![CDATA['.$toUsername.']]></FromUserName>
                     <CreateTime>'.$time.'</CreateTime>
                     <MsgType><![CDATA[news]]></MsgType>
                     <ArticleCount>' . count($graphicArr) . '</ArticleCount>
                     <Articles>';
        foreach ($graphicArr as $k => $v) {
            $template .= '<item>
                          <Title><![CDATA[' . $v['title'] . ']]></Title>
                          <Description><![CDATA[' . $v['description'] . ']]></Description>
                          <PicUrl><![CDATA[' . $v['picurl'] . ']]></PicUrl>
                          <Url><![CDATA[' . $v['url'] . ']]></Url>
                          </item>';
        }
        $template .= '</Articles>
                      </xml> ';
//        echo   $spr = sprintf($template, $fromUsername, $toUsername, $time, 'news');
        echo $template;
//        $this->debug($spr);
    }

    //debug变量的值
    public function debug($var)
    {
        $postObj = $this->sdkInit();
        if (is_array($var) || is_object($var) || is_bool($var)) {
            $this->responseTextMsg($postObj, var_export($var, true));
        } else
            $this->responseTextMsg($postObj, $var);
        exit;
    }

    //CURL方法
    public function curlGet($url)
    {
        //初始化
        $ch = curl_init();
        //设置选项，包括URL
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        //执行并获取HTML文档内容
        $output = curl_exec($ch);
        if (curl_errno($ch)) {
            $this->debug(curl_error($ch));
        }
        //释放curl句柄
        curl_close($ch);

        return $output;
    }

    //$postData是数组形式
    public function curlPost($url, $postData)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // post数据
        curl_setopt($ch, CURLOPT_POST, 1);
        // post的变量
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        $output = curl_exec($ch);
        if (curl_errno($ch)) {
            $this->debug(curl_error($ch));
        }
        curl_close($ch);

        return $output;
    }

    //初始化Memcache
    public function memcacheInit()
    {
        $option = array(
            'type' => 'memcache',
            'host' => '127.0.0.1',
            'port' => '11211',
            'timeout' => 10,
            'expire' => 7000,
            'prefix' => 'lanl_',
        );
        $cache = Cache::connect($option);
        return $cache;
    }

    //获取并缓存access_token,生命周期7000s
    public function curlGetAccessToken()
    {

        if (!defined("APPID") && !defined("APPSECRET")) {
            throw new \think\Exception('APPID and APPSECET is not defined!');
        }
        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . APPID . '&secret=' . APPSECRET;
        if ($res = json_decode($this->curlGet($url), true)) {
            //$res有两个参数：access_token 和 expires_in
            return $res;
        } else
            return false;
    }

    //用Memcache服务器缓存access_token，参数$key表示保存的access_token的键名
    public function getAccessToken($tag = '',$key)
    {
        $cache = $this->memcacheInit();
//        $cache->clear($tag);
        if (!$cache->has($key)) {
            if ($res = $this->curlGetAccessToken()){
                $accessToken = $res['access_token'];
                $cache->tag($tag)->set($key, $accessToken, 7000);//生命周期7000s
            }else
                return false;

        }else
            $accessToken = $cache->get($key);
        return $accessToken;
    }

    //创建微信自定义菜单
    //注意$menuArr数组定义时需要用urlencode将中文字符转义，不然会出错
    public function defineMenu($tag = '',$key, $menuArr)
    {
        if(!$accessToken = $this->getAccessToken($tag,$key)){
            return false;
        }
        $url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token=' . $accessToken;
        $postArr = array(
            'button' => $menuArr
        );
        $postArr = urldecode(json_encode($postArr));
        return $this->curlPost($url, $postArr);
    }
    public function wechatHotSpider($keyword ,$limitDay = 1,$name = 'wechatHot'){
        /*
         * $keyword 关键字 string
         * $limitDay 时间限制 int   (1,2,3,4,0 : 1天，1周，1月，1年，全部时间)
         */
        $cache = $this->memcacheInit();
//        $cache->clear('curl');
        if($cache->has($name)){
            return $cache->get($name);
        }else{
            $url = "http://weixin.sogou.com/weixin?type=2&ie=utf8&query=".$keyword;
            if($limitDay){
                $url .= "&tsn=".$limitDay;
            }
            $url .= "&ft=&et=&interation=&wxid=&usip=";
            $curlobj = curl_init();			// 初始化
            curl_setopt($curlobj, CURLOPT_URL, $url);		// 设置访问网页的URL
            curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, true);			// 执行之后不直接打印出来
            curl_setopt($curlobj, CURLOPT_FOLLOWLOCATION,1);
            //生成随机国内IP
            $ip_long = array(
                array('607649792', '608174079'), //36.56.0.0-36.63.255.255
                array('1038614528', '1039007743'), //61.232.0.0-61.237.255.255
                array('1783627776', '1784676351'), //106.80.0.0-106.95.255.255
                array('2035023872', '2035154943'), //121.76.0.0-121.77.255.255
                array('2078801920', '2079064063'), //123.232.0.0-123.235.255.255
                array('-1950089216', '-1948778497'), //139.196.0.0-139.215.255.255
                array('-1425539072', '-1425014785'), //171.8.0.0-171.15.255.255
                array('-1236271104', '-1235419137'), //182.80.0.0-182.92.255.255
                array('-770113536', '-768606209'), //210.25.0.0-210.47.255.255
                array('-569376768', '-564133889'), //222.16.0.0-222.95.255.255
            );
            $rand_key = mt_rand(0, 9);
            $ip= long2ip(mt_rand($ip_long[$rand_key][0], $ip_long[$rand_key][1]));
            curl_setopt($curlobj, CURLOPT_HTTPHEADER, array('X-FORWARDED-FOR:183.36.114.45:80', 'CLIENT-IP:'.$ip));
            curl_setopt($curlobj, CURLOPT_REFERER, $url);
            curl_setopt($curlobj, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0");
            $output = curl_exec($curlobj);
//            echo $output;
            curl_close($curlobj);			// 关闭cURL
            include_once "../public/simple_html_dom.php";
            $dom = new \simple_html_dom();
            $dom->load($output);
            $newsList = $dom->find('ul[class=news-list]',0);
            $temp = array();
            $count = count($newsList->children);
            for($i=1,$j=0;$i<$count;$i+=3,$j++){
                if($newsList->children($i)->children(0)->attr['class'] == 'img-box'){
                    $temp[$j]['title'] = trim( html_entity_decode($newsList->children($i)->children(1)->children(0)->plaintext));
                    $temp[$j]['description'] = trim( html_entity_decode($newsList->children($i)->children(1)->children(1)->plaintext));
                    $temp[$j]['picurl'] = html_entity_decode($newsList->children($i)->children(0)->children(0)->children(0)->attr['src']);
                    $temp[$j]['url'] = html_entity_decode($newsList->children($i)->children(0)->children(0)->attr['href']);
                }else{
                    $j--;
                }
            }
            $cache->tag('curl')->set($name,$temp ,7200);    // 缓存7200s
            return $cache->get($name) ;
        }
    }

}